/*
 * common_tools.h
 */

#ifndef COMMON_TOOLS_H_
#define COMMON_TOOLS_H_

#include <iostream>
#include <utility>
#include <random>

namespace san {  // namespace san

template <typename T, typename F = std::less<T>>
int compare(const T &v1, const T &v2, F f = F())
{
	if (f(v1, v2)) return -1;
	if (f(v2, v1)) return 1;
	return 0;
}


template<typename Iterator, typename Value>
Iterator find(Iterator first, Iterator last, Value value)
{
	while (first != last)
	{
		if (*first == value)
			return first;
		++first;
	}
	return last;
}

template<typename Array>
void print(const Array &arr)
{
	for (const auto &item: arr)
	{
		std::cout << item << " ";
	}
}

template<typename Iterator>
void print(Iterator first, Iterator last)
{
	while (first != last)
	{
		std::cout << *first << " ";
		++first;
	}
	std::cout << std::endl;
}

template<typename T, unsigned N>
T *begin(const T (&arr)[N])
{
	return arr;
}

template<typename T, unsigned N>
T *end(const T (&arr)[N])
{
	return arr + N;
}

template<typename T, unsigned N> constexpr
unsigned size(const T (&arr)[N])
{
	return N;
}

template <typename Container>
void print_container(const Container &c)
{
	// 遍历一个元素
	for (typename Container::size_type i = 0; i < c.size(); ++i )
	{
		std::cout << c[i] << " ";
	}
	std::cout << std::endl;
}

template <typename It>
auto fcn3(It beg, It end, size_t n) -> decltype(*beg + 0)
{
	// 接收一个迭代器范围，返回第n个元素（从0开始）
	if (n >= end - beg)
		throw std::out_of_range("out of range!");
	return *(beg + n);
}

template <typename A, typename B>
auto sum(const A &a, const B &b) -> decltype(a + b)
{
	// 返回加法结果
	return a + b;
}

template <typename F, typename T1, typename T2>
void flip(F f, T1 &&t1, T2 &&t2)
{
	f(std::forward<T2>(t2), std::forward<T1>(t1));
}

std::vector<unsigned> get_random(unsigned min, unsigned max);

}  // namespace san

#endif
